﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SteamFluentAPI.Builder;
using SteamFluentAPI.Infrastructure.MetaData;

namespace SteamFluentAPI
{
    /// <summary>
    /// Intuitive way to request data from Valve's Steam Web API service using fluent design pattern.
    /// </summary>
    public class SteamAPI
    {
        #region Globals

        private static SteamRequestFormat _requestFormat = SteamRequestFormat.JSON;

        /// <summary>
        /// Sets all Steam Requests to follow the specified format.
        /// </summary>
        /// <param name="requestFormat"></param>
        public static void GlobalSteamRequestFormat(SteamRequestFormat requestFormat)
        {
            _requestFormat = requestFormat;
        }

        private static string _apiKey = ConfigurationManager.AppSettings["APIKey"];

        /// <summary>
        /// Sets all Steam Requests to use the specified API Key.
        /// </summary>
        /// <param name="apiKey"></param>
        public static void GlobalAPIKey(string apiKey)
        {
            _apiKey = apiKey;
        }

        private static string _languageCode = "en-US";

        /// <summary>
        /// Sets all Steam Requests to return results with the specified languageCode.
        /// </summary>
        /// <param name="languageCode"></param>
        public static void GlobalLanguageCode(string languageCode)
        {
            _languageCode = languageCode;
        }

        #endregion

        #region Request

        /// <summary>
        /// <para>Begins a new SteamRequestBuilder to construct a query string for Steam Web API.</para>
        /// <para>Assumes that the API Key is supplied within the configuration file under AppSettings as "APIKey".</para>
        /// <para>Assumes that the response format will be in JSON.</para>
        /// <para>Assumes that the language code will be en-US</para>
        /// <para><see href="http://steamcommunity.com/dev/apikey">See here</see></para>
        /// </summary>
        /// <returns></returns>
        public static SteamRequestBuilder Request()
        {
            return SteamAPI.Request(_requestFormat);
        }
        /// <summary>
        /// <para>Begins a new SteamRequestBuilder to construct a query string for Steam Web API.</para>
        /// <para>Assumes that the API Key is supplied within the configuration file under AppSettings as "APIKey".</para>
        /// </summary>
        /// <param name="steamRequestFormat">Format of the requested data.</param>
        /// <returns></returns>
        public static SteamRequestBuilder Request(SteamRequestFormat steamRequestFormat)
        {
            if (string.IsNullOrEmpty(_apiKey))
            {
                throw new ApplicationException("APIKey not found. Please check your app settings or supply an API Key as a parameter for SteamRequestBuilder.");
            }

            return SteamAPI.Request(_apiKey, steamRequestFormat);
        }
        /// <summary>
        /// <para>Begins a new SteamRequestBuilder to construct a query string for Steam Web API.</para>
        /// <para>Assumes that the response format will be in JSON.</para>
        /// </summary>
        /// <param name="apiKey">API key generated by Valve for developers.</param>
        /// <returns></returns>
        public static SteamRequestBuilder Request(string apiKey)
        {
            return SteamAPI.Request(apiKey, SteamRequestFormat.JSON);
        }
        /// <summary>
        /// <para>Begins a new SteamRequestBuilder to construct a query string for Steam Web API.</para>
        /// </summary>
        /// <param name="apiKey">API key generated by Valve for developers.</param>
        /// <param name="steamRequestFormat">Format of the requested data.</param>
        /// <returns></returns>
        public static SteamRequestBuilder Request(string apiKey, SteamRequestFormat steamRequestFormat)
        {
            return SteamAPI.Request(apiKey, steamRequestFormat, _languageCode);
        }
        /// <summary>
        /// <para>Begins a new SteamRequestBuilder to construct a query string for Steam Web API.</para>
        /// </summary>
        /// <param name="apiKey">API key generated by Valve for developers.</param>
        /// <param name="steamRequestFormat">Format of the requested data.</param>
        /// <param name="languageCode">Language code format of the requested data.</param>
        /// <returns></returns>
        public static SteamRequestBuilder Request(string apiKey, SteamRequestFormat steamRequestFormat, string languageCode)
        {
            return new SteamRequestBuilder(apiKey, steamRequestFormat, languageCode);
        }

        #endregion

        #region Meta Data

        private static SteamMetaDataCollection _metaDataCollection;
        /// <summary>
        /// Returns a collection of meta data related to Steam Web API interfaces, methods and parameters.
        /// </summary>
        public static SteamMetaDataCollection MetaData
        {
            get
            {
                if (_metaDataCollection == null)
                {
                    _metaDataCollection = new SteamMetaDataCollection();
                }
                return _metaDataCollection;
            }
        }

        #endregion

        #region Hiding Methods

        [EditorBrowsable(EditorBrowsableState.Never)]
        public override Boolean Equals(Object obj)
        {
            return base.Equals(obj);
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public override Int32 GetHashCode()
        {
            return base.GetHashCode();
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public override String ToString()
        {
            return base.ToString();
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public new Type GetType()
        {
            return base.GetType();
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public static new bool ReferenceEquals(object objA, object objB)
        {
            return SteamAPI.ReferenceEquals(objA, objB);
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public static new bool Equals(object objA, object objB)
        {
            return SteamAPI.Equals(objA, objB);
        }

        #endregion
    }
}
